// #include <iostream>
// #include <mutex>
// #include <condition_variable>
// #include <queue>
// #include <thread>
// #include <vector>

// // 定义一个简单的阻塞队列
// template<typename T>
// class BlockingQueue {
// public:
//     void push(T value) {
//         std::unique_lock<std::mutex> lock(mutex_);
//         queue_.push(std::move(value));
//         // 通知一个等待的线程（如果有的话）
//         condition_.notify_one();
//     }

//     bool try_pop(T& value) {
//         std::unique_lock<std::mutex> lock(mutex_);
//         // 等待直到队列中有元素或线程被中断
//         condition_.wait(lock, [this]() { return !queue_.empty(); });
//         // 如果队列不为空，则弹出一个元素
//         if (!queue_.empty()) {
//             value = std::move(queue_.front());
//             queue_.pop();
//             return true;
//         }
//         return false;
//     }

// private:
//     std::queue<T> queue_;
//     std::mutex mutex_;
//     std::condition_variable condition_;
// };

// // 生产者线程函数
// void producer(BlockingQueue<int>& queue, int id) {
//     for (int i = 0; i < 10; ++i) {
//         // 生产数据
//         int data = id * 10 + i;
//         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟生产时间
//         // 将数据放入队列
//         queue.push(data);
//         std::cout << "Producer " << id << " produced " << data << std::endl;
//     }
// }

// // 消费者线程函数
// void consumer(BlockingQueue<int>& queue) {
//     while (true) {
//         int data;
//         // 尝试从队列中取出数据
//         if (queue.try_pop(data)) {
//             // 处理数据
//             std::cout << "Consumer processed " << data << std::endl;
//         } else {
//             // 队列为空，退出循环
//             break;
//         }
//     }
// }

// int main() {
//     BlockingQueue<int> queue;

//     // 创建生产者线程
//     std::vector<std::thread> producers;
//     for (int i = 0; i < 2; ++i) {
//         producers.emplace_back(producer, std::ref(queue), i + 1);
//     }

//     // 创建消费者线程
//     std::vector<std::thread> consumers;
//     for (int i = 0; i < 3; ++i) {
//         consumers.emplace_back(consumer, std::ref(queue));
//     }

//     // 等待生产者线程完成
//     for (auto& t : producers) {
//         t.join();
//     }

//     // 通知所有消费者线程队列已空，并等待它们完成
//     for (auto& t : consumers) {
//         t.join();
//     }

//     return 0;
// }

//Linux
#include<iostream>
#include<pthread.h>
#include<queue>
#include<stdlib.h>

#define NUM 8

//阻塞队列
class BlockQueue
{
   public:
   //构造
   BlockQueue(int _cap =NUM)
   :cap(_cap)
   {
     pthread_mutex_init(&lock,NULL);
     pthread_cond_init(&full,NULL);
     pthread_cond_init(&empty,NULL);
   }
   //析构
   ~BlockQueue()
   {
      
      pthread_mutex_destroy(&lock);
      pthread_cond_destroy(&full);
      pthread_cond_destroy(&empty);
   }
   
   //生产者往阻塞队列里生产数据
   void PushData(const int &data)
   {
    LockQueue();
    while(IsFull())
    {
        NotifyConsume();
         //         队列已满，  通知消费数据，         启动停止
        std::cout<<"queue full,notify consume data,priduct stop."<<std::endl;
        ProductWait();
    }
    q.push(data);
    NotifyConsume();
    UnLockQueue();
   }
   //消费者往外拿数据
   void PopData(int&data)
   {
    LockQueue();
    while(IsEmpty())
    {
        NotifyProduct();
        std::cout<<"queue empty,notify product data ,consume stop"<<std::endl;
        ConsumeWait();
    }
    data =q.front();//拿数据给data
    q.pop();
    NotifyProduct();
    UnLockQueue();
   }

    private:
    //加锁
    void LockQueue()
    {
        pthread_mutex_lock(&lock); 
    }
    //解锁
    void UnLockQueue()
    {
        pthread_mutex_unlock(&lock); 
    }
    //生产者等待
    void ProductWait()
    {
        pthread_cond_wait(&full,&lock);
    }
     //消费者等待
    void ConsumeWait()
    {
        pthread_cond_wait(&empty,&lock);
    }
    //生产者唤醒
    void NotifyProduct()
    {
        pthread_cond_signal(&full);
    }
    //消费者唤醒
    void NotifyConsume()
    {
        pthread_cond_signal(&empty);
    }
    //判断队列是否为空
    bool IsEmpty()
    {
        return (q.size() == 0 ? true : false);
    }
    //判断队列是否为满
    bool IsFull()
    {
        return (q.size() == cap ? true : false);
    }



    private:
    std::queue<int> q; //队列
    int cap;          //队列容量
    pthread_mutex_t lock; //定义锁
    //生产者和消费者的条件变量，判断生产消费是否满足条件
    pthread_cond_t full;
    pthread_cond_t empty;
};

//函数指针的定义
//返回类型 (*指针名称)(参数类型列表);
// 定义一会俩个线程需要跑的函数
//消费者线程函数，它不断地从阻塞队列中取出数据，并打印消费的数据
void *consumer(void *arg)
{
   BlockQueue *bqp = (BlockQueue*)arg;
   int data;
   for( ; ; )
   {
   bqp->PopData(data);
   std::cout << "Consume data done : " << data << std::endl;
   }
}
//生产者线程函数，它不断地生成随机数据，并将其添加到阻塞队列中，然后打印生产的数据。
void *producter(void *arg)
{
   BlockQueue *bqp = (BlockQueue*)arg;
   srand((unsigned long)time(NULL));
   for( ; ; )
   {
   int data = rand() % 1024;
   bqp->PushData(data);
   std::cout << "Prodoct data done: " << data << std::endl;
   // sleep(1);
   }
}

int main ()
{
  BlockQueue bq;//创建一个阻塞队列bq
  pthread_t c,p; //创建俩个线程
  
  pthread_create(&c,NULL,consumer,(void*)&bq);//消费者
  pthread_create(&p,NULL,producter,(void*)&bq);//生产者

  pthread_join(c,NULL);
  pthread_join(p,NULL); //等待线程结束
  return 0;
}

